Question:
Use of Singletons in .NET Core in AWS Lambda

Following the general phenomena you should never cache anything in the AWS Lambda. It’s better to analyse the output when you do the cache. See whether a codebase appear that is carrying out this process and if you are having problems with it. 


Today, Deficiency Injection is extremely common, here we will use the singleton service in AWS Lambda. Woring with AWS Lambda is not easy. If you are used to long processes this process will not tire you. When you deploy new code or your app crashes, your DI container is re-created and re-instantiated in the long process.


In this article, we will tell you how to use singleton in .NET Core in AWS Lambda. Read this full article, to understand the steps for use of Singleton in AWS Lambda.


If you want to >migrate your app from Haruko to AWS then our blog will guide you through. We have mentioned 5 simple steps to migrate your application. 


                                                      Source: >Steady Coding


The above picture clearly shows that there is a download code and setup. What does ‘Initialization and start of the code’ means? The picture shows that it’s on the side of users which give us control. Now another question occur, whether it is initiated the C# class for the Lambda dependency injection and constructor is called, or this is a part of Code Execution? Additionally, AWS Lambda is carry out in the container. What does this means? Is it warm starts the container or is it already started?


This is crucial information to know since it will indicate whether or not our DI container is instantiated only once for each cold start or for each warm start as well, given that our constructor instantiates our DI container.


We can do ‘Initialization and start the code’ describe that we have the C# object in the memory, and in case you have setup the DI container with the help of singletons in the constructor then each warm start will again use these singleton services all the time. This C# injection process will go on until your AWS Lambda requires the cold start. 


The following code example will help you think rationally. The following code is the simple dependency function for the .NET Lambda function:


public class Function

{

    private static ServiceProvider ServiceProvider { get; set; }


    /// <summary>

    /// The parameterless constructor is what Lambda uses to construct your instance the first time.

    /// It will only ever be called once for the lifetime of the container that it's running on.

    /// We want to build our ServiceProvider once, and then use the same provider in all subsequent 

    /// Lambda invocations. This makes things like using local MemoryCache techniques viable (Just 

    /// remember that you can never count on a locally cached item to be there!)

    /// </summary>

    public Function()

    {

        var services = new ServiceCollection();

        ConfigureServices(services);

        ServiceProvider = services.BuildServiceProvider();

    }


    public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context)

    {

        await ServiceProvider.GetService<App>().Run(evnt);

    }


    /// <summary>

    /// Configure whatever dependency injection you like here

    /// </summary>

    /// <param name="services"></param>

    private static void ConfigureServices(IServiceCollection services)

    {

        // add dependencies here ex: Logging, IMemoryCache, Interface mapping to concrete class, etc...


        // add a hook to your class that will actually do the application logic

        services.AddTransient<App>();

    }


    /// <summary>

    /// Since we don't want to dispose of the ServiceProvider in the FunctionHandler, we will

    /// at least try to clean up after ourselves in the destructor for the class.

    /// </summary>

    ~Function()

    {

        ServiceProvider.Dispose();

    }

}

// Class copied from: https://stackoverflow.com/a/54166289/2874896


The above code miss one new scope in the function handle which will resolve the scope service. If you don’t carry out this function then you will get multiple calls or request to your Lambda which could receive the same scoped service. 


The following code is the improved version of the function which address this issue. 


public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context)

{

    // Calling CreateScope() here is required to resolve scoped services correctly

    using var scope = ServiceProvider.CreateScope();

    await scope.ServiceProvider.GetService<App>().Run(evnt);

}

What does the above code tell us?

  • When a warm start request can be handled by your Lambda, your constructor won't be called.


  • A DI container shouldn't be put up in your FunctionHandler method because it would then be created on each warm start as well.


  • It will be cached for all subsequent warm start invocations if you wire up your DI container in the constructor and cache something without an expiration date in a singleton service.


  • Your cache will be empty at the subsequent cold start if you wire up your DI container in the constructor and cache something in a singleton service. Although there doesn't appear to be a set point at which a cold start happens, this post claims that the likelihood is high after 5-7 minutes if there is no traffic.


  • You cannot utilize a singleton service if you wish to cache something for the duration of only one specific invocation, but you could wire up your service as scoped in its place.


  • One time every cold start, your AWS Lambda container (not to be confused with the DI container) is started (and maintained running).








 

Ritu Singh

Ritu Singh

Submit
0 Answers